package com.cqc.lite.utils;


import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * PrintWriter + BufferedReader
 *
 */
public class CsvUtil {

    //字符集： UTF-8  GBK
    public static String charsetName = "GBK";
    //分隔符
    public static String delimiter = ",";

    /**
     * 生成CSV文件并保存在指定目录
     * @param head       文件头
     * @param dataList   数据列表
     * @param outPutPath 文件输出路径
     * @param filename   文件名  xx.csv
     */
    public static File createCSVFile(List<Object> head, List<List<Object>> dataList, String outPutPath, String filename) {
        File csvFile = null;
        PrintWriter writer = null;
        try {
            csvFile = new File(outPutPath + File.separator + filename);
            File parent = csvFile.getParentFile();
            if (parent != null && !parent.exists()) {
                boolean mkdirs = parent.mkdirs();
                if(!mkdirs){
                    return null;
                }
            }
            boolean newFile = csvFile.createNewFile();
            if(!newFile){
                return null;
            }

            writer = new PrintWriter(csvFile, charsetName);
            // 写入文件头部
            writeRow(head, writer);

            // 写入文件内容
            for (List<Object> row : dataList) {
                writeRow(row, writer);
            }
            writer.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            close(writer);
        }
        return csvFile;
    }


    /**
     * 导出csv文件
     * @param headList     文件头
     * @param dataList 数据列表
     * @param fileName xx.csv
     */
    public static void downloadCsv(HttpServletRequest request, HttpServletResponse response,
                                   List<Object> headList, List<List<Object>> dataList, String fileName) {
        //设置下载的响应头信息
        response.setCharacterEncoding(charsetName);
        response.setHeader("content-disposition", "attachment;filename=" + fileName);
        String mimeType = request.getSession().getServletContext().getMimeType(fileName);
        response.setContentType(mimeType);

        PrintWriter writer = null;
        try {
            writer = new PrintWriter(response.getOutputStream());
            // 写入文件头部
            writeRow(headList, writer);
            // 写入文件内容
            for (List<Object> row : dataList) {
                writeRow(row, writer);
            }
            writer.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            close(writer);
        }
    }

    private static void close(Closeable stream) {
        if (null != stream) {
            try {
                stream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }



    /**
     * 写一行数据方法
     *
     * @param row
     * @param csvWriter
     * @throws IOException
     */
    private static void writeRow(List<Object> row, PrintWriter csvWriter) throws IOException {
        // 写入文件头部
        for (Object data : row) {
            StringBuffer sb = new StringBuffer();
            //给每个单元格的数据不要加引号,因为本身就是String，否则读取的时候会读到4个双引号 ""第一列""
//            String rowStr = sb.append("\"").append(data).append("\"").append(delimiter).toString();
            String rowStr = sb.append(data).append(delimiter).toString();
            csvWriter.write(rowStr);
        }
        csvWriter.write("\r\n");
    }

    /**
     * 读取CSV数据(包含头信息)
     */
    public static List<List<String>> readCsv(String filePath) {
        BufferedReader reader = null;
        List<List<String>> dataList = new ArrayList<>();
        try {
            File file = new File(filePath);
            reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), charsetName));
            //去掉头信息：头部有几行，就执行几次reader.readLine();
            String lineStr = null;
            while ((lineStr = reader.readLine()) != null) {
                //一行的数据
                List<String> rows = new ArrayList<>();
                String[] arr = lineStr.split(delimiter);
                //把array加入到rows集合中
                Collections.addAll(rows, arr);
                dataList.add(rows);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            close(reader);
        }
        return dataList;
    }

    /**
     * 读取CSV数据(包含头信息)
     */
    public static List<List<String>> readCsv(MultipartFile multipartFile) {
        BufferedReader reader = null;
        List<List<String>> dataList = new ArrayList<>();
        try {
            reader = new BufferedReader(new InputStreamReader(multipartFile.getInputStream(), charsetName));
            //去掉头信息：头部有几行，就执行几次reader.readLine();
            String lineStr = null;
            while ((lineStr = reader.readLine()) != null) {
                //一行的数据
                List<String> rows = new ArrayList<>();
                String[] arr = lineStr.split(delimiter);
                //把array加入到rows集合中
                Collections.addAll(rows, arr);
                dataList.add(rows);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            close(reader);
        }
        return dataList;
    }




    //---------------------------test----------------------------
    public static void main(String[] args) {
        readCSV();
//        writeCSV();
    }

    private static void readCSV() {
        String filePath = "C:\\Users\\cui\\Desktop\\文件导出.csv";
        List<List<String>> dataList = readCsv(filePath);
        for (List<String> rows : dataList) {
            for (String o : rows) {
                System.out.print(o+"  ");
            }
            System.out.println();
        }
    }

    private static void writeCSV() {
        List<Object> headList = new ArrayList<Object>();
        headList.add("第一列");
        headList.add("第二列");
        headList.add("第三列");
        List<List<Object>> rowList = new ArrayList<List<Object>>();
        List<Object> data = new ArrayList<Object>();
        data.add("111");
        data.add("222");
        data.add("333");
        List<Object> data1 = new ArrayList<Object>();
        data1.add("444");
        data1.add("555");
        data1.add("666");
        rowList.add(data);
        rowList.add(data1);
        String path = "C:\\Users\\cui\\Desktop";
        String fileName = "文件导出.csv";

        File file = CsvUtil.createCSVFile(headList, rowList, path, fileName);
    }
}
